/***************************************************************************
 *   mgpi_compmdl.h - Components Model Declarations                        *
 *   Copyright (C) 2008 by cmaster.matso                                   *
 *   cmaster.matso@gmail.com                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef _COMPMDL_H
#define _COMPMDL_H

#ifdef __cplusplus
extern "C" {
#endif

#include "../../mgpi_game.h"

#define MGPI_MAX_EVENT_TYPES 14                                                 /** max number of component/container events types */

#pragma pack(push, 1)

    typedef struct _comp {
        int flags[8];															/** set of useful flags */
        int id;																	/** used as index in components table */
        void *parent;															/** not NULL if the component is within a container */
        void *logic;															/** component logic layer */

        MGPI_BOOL(*onEvent[MGPI_MAX_EVENT_TYPES])(struct _comp *, SDL_Event *);	/** pointers to event handling routines */
        MGPI_BOOL(**onUserEvent)(void *, SDL_Event *);							/** pointers to variouse event handling routines */
    } comp_t;																	/** structure used for event dealing and thread communication */

    typedef struct _lstcmp {
        comp_t *component;
        struct _lstcmp *next;
        struct _lstcmp *prev;
    } lstcmp_t;																	/** structure of components bi-directional list */

    typedef struct _cont {
        int comp_num;															/** number of components */
        int cont_num;															/** number of containers */

        comp_t component;														/** container's own-component variable (container is a component) */

        comp_t **comp_array;													/** components pointers array */
        lstcmp_t comp_list;														/** handle to components bi-directional list */

        struct _cont **cont_array;												/** containers pointers array */
        struct _lcont {
            struct _cont *container;
            struct _lcont *next;
            struct _lcont *prev;
        } cont_list;															/** handle to containers bi-derectional list */

        comp_t * (*getComponent)(struct _cont *, int);							/** Gets component of given index (IMPLEMET)*/
        void (*addComponent)(struct _cont *, comp_t *);							/** Adds given component to the container (IMPLEMET)*/
        void (*removeComponent)(struct _cont *, int);							/** Removes component of given index from the container (IMPLEMET)*/

        struct _cont * (*getContainer)(struct _cont *, int);					/** Gets container of given index (IMPLEMET)*/
        void (*addContainer)(struct _cont *, struct _cont *);					/** Adds given container to the container (IMPLEMET)*/
        void (*removeContainer)(struct _cont *, int);							/** Removes container of given index from the container (IMPLEMET)*/
    } cont_t;																	/** structure assembling a number of components - extended component (for 3D usage) */

    typedef struct _lstcnt lstcnt_t;											/** structure of containers bi-directional list */

#pragma pack(pop)

    /**
     * Initializes given container, or the root one (if given is NULL), to default values.
     */
    void MGPI_API MGPI_InitContainer(cont_t *c);

    /**
     * Gets root container's component (for event handling usage).
     */
    MGPI_API comp_t *MGPI_GetRootComponent(void);

    /**
     * Gets the root container (framework internal usage only).
     */
    cont_t *MGPI_GetRootContainer(void);

#ifdef __cplusplus
}
#endif

#endif
